package com.server;

import com.common.AttributeKey;
import com.common.Channel;
import com.common.ChannelFuture;
import com.common.ChannelInitializer;
import com.common.ChannelOption;
import com.common.EventLoopGroup;
import com.common.NioEventLoopGroup;
import com.common.NioServerSocketChannel;
import com.common.ServerBootstrap;
import com.common.StringDecoder;
import com.common.StringEncoder;
import com.server.ServerHandler;

/**
 * netty5服务端
 *
 */
public class Server {

	public static void main1(String[] args) {
		// 服务类
		ServerBootstrap bootstrap = new ServerBootstrap();

		// boss和worker，
		//第一个称为“boss”，用来accept客户端连接，
		//第二个称为“worker”，处理客户端数据的读写操作。
		//当然你也可以只用一个NioEventLoopGroup同时来处理连接和读写，bootstrap.group()方法支持一个参数。
		EventLoopGroup boss = new NioEventLoopGroup(2);
		EventLoopGroup worker = new NioEventLoopGroup(1);

		try {
			// 设置线程池
//			bootstrap.group(boss, worker); // 设置group，childGroup。接收连接和处理读写的channel分在2个
			bootstrap.group(worker);//接收连接和处理读写的channel都绑定在一个NioEventLoop上面处理
			// 设置socket工厂。保存在AbstractBootstrap的成员变量。设置channelFactory
			bootstrap.channel(NioServerSocketChannel.class);//channel指定NIO方式

			// 设置管道工厂，设置进了客户端channl的管道中。
			//childHandler指定编解码器，处理数据的Handler
			bootstrap.childHandler(new ChannelInitializer<Channel>() {
				@Override
				protected void initChannel(Channel ch) throws Exception {
					ch.pipeline().addLast(new StringDecoder());
					ch.pipeline().addLast(new StringEncoder());
					ch.pipeline().addLast(new ServerHandler());
				}
			});

			bootstrap.handler(new ServerHandler());
			// netty3中对应设置如下
			// bootstrap.setOption("backlog", 1024);
			// bootstrap.setOption("tcpNoDelay", true);
			// bootstrap.setOption("keepAlive", true);
			// 设置参数，TCP参数
			bootstrap.option(ChannelOption.SO_BACKLOG, 2048);// serverSocketchannel的设置，链接缓冲池的大小。
																// 保存在AbstractBootstrap的成员变量。
			bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);// socketchannel的设置,维持链接的活跃，清除死链接。
																	// 保存在ServerBootstrap的成员变量。
			bootstrap.childOption(ChannelOption.TCP_NODELAY, true);// socketchannel的设置,关闭延迟发送。保存在ServerBootstrap的成员变量。
			bootstrap.childAttr(AttributeKey.newInstance("childAttr"), "childAttrValue");// 保存在ServerBootstrap的成员变量。
			// 绑定端口启动服务
			ChannelFuture future = bootstrap.bind(8888);// 初始化一个服务端的channel

			System.out.println("start");

			// 等待服务端关闭
			future.channel().closeFuture().sync();

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 释放资源
			boss.shutdownGracefully();
			worker.shutdownGracefully();
		}
	}
}
